<template>
  <div class="manga-info">
    <div class="top" :style="[bannerModel === 'toomics' && {marginTop: 0}]">
      <template v-if="banner.length">
        <el-carousel class="carousel" :interval="interval" :type="carouselType" v-if="bannerModel === 'toptoon'">
          <el-carousel-item class="banner-box" v-for="item in banner" :key="item.metaId">
            <img class="banner" :src="item.blob" alt="banner" />
          </el-carousel-item>
          <!-- 使用一张图片撑开容器的高度 -->
          <img class="banner seat" :src="banner.length ? banner[0].blob : ''" alt="banner" />
        </el-carousel>

        <div class="banner-toomics" v-if="bannerModel === 'toomics'">
          <img class="banner-toomics-fore" :src="banner[0]?.blob" alt="banner" />
          <img class="banner-toomics-back" :src="bannerBg?.blob" alt="bannerBg" />
        </div>
      </template>

      <el-image class="anim cover-img" :src="mangaCover" fit="contain" v-else></el-image>
    </div>

    <div class="middle">
      <div class="character" @wheel="character_wheel" v-if="character.length">
        <p class="character-title">角色</p>
        <div class="character-scroll" @wheel="character_wheel" :options="{suppressScrollX: false, suppressScrollY: true}">
          <div v-for="item in character" class="character-item" :key="item.characterId">
            <img :src="item.blob" :alt="item.metaContent" />
            <div class="right">
              <p class="name">{{ item.metaContent }}</p>
              <p class="description">{{ item.description }}</p>
            </div>
          </div>
        </div>
      </div>

      <el-descriptions class="meta-info" title="漫画信息" :column="infoColum">
        <el-descriptions-item label="漫画名称">{{ mangaInfo.mangaName }}</el-descriptions-item>
        <el-descriptions-item label="作者">{{ mangaInfo.author }}</el-descriptions-item>
        <el-descriptions-item label="发布时间">{{ mangaInfo.publishDate }}</el-descriptions-item>
        <el-descriptions-item label="章节总数">{{ mangaInfo.chapterCount }}</el-descriptions-item>
        <el-descriptions-item label="阅读方式">{{ mangaInfo.browseType }}</el-descriptions-item>
        <el-descriptions-item label="所属媒体库">{{ mangaInfo.media?.mediaName }}</el-descriptions-item>
        <el-descriptions-item label="入库时间">{{ mangaInfo.createTime }}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{ mangaInfo.updateTime }}</el-descriptions-item>
        <el-descriptions-item label="评分">{{ mangaInfo.star }}</el-descriptions-item>
        <el-descriptions-item label="标签">
          <el-tag v-for="item in mangaInfo.tags" :key="item.tagId" class="tag" size="small" :color="item.tagColor">{{ item.tagName }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="简介">{{ mangaInfo.describe }}</el-descriptions-item>
      </el-descriptions>

      <div class="btn-box">
        <el-button class="btn" type="primary" @click="go_chapter_list">章节列表</el-button>

        <el-button class="btn continue-read" type="warning" @click="go_chapter" v-if="hasLatest">
          {{ userConfig.continueReadButtonShowChapterNumberOnly ? continueRead.chapterNumber : continueRead.chapterName }}
          第{{ continueRead.page }}页
        </el-button>
        <el-button class="btn" type="success" @click="go_chapter" v-else>开始阅读</el-button>

        <el-button class="btn" type="warning" @click="remove_collect" v-if="isCollect">取消收藏</el-button>
        <el-button class="btn" type="success" @click="collect_manga" v-else>收藏漫画</el-button>

        <el-button class="btn" type="success" @click="mangaShareDialog = true">分享漫画</el-button>

        <el-button class="btn" type="primary" @click="editMangaDialog = true">编辑漫画</el-button>
        <el-button class="btn" type="primary" @click="editTagsDialog = true">编辑标签</el-button>
        <el-button class="btn" type="primary" @click="open_covers_edit" v-if="hasManyCover">编辑封面</el-button>
        <el-button class="btn" type="primary" @click="open_metas_edit">编辑元数据</el-button>
      </div>

      <el-form-item :label="$t('mangaInfo.reverseOrder')" class="op-range">
        <el-switch v-model="chapterListDesc" @change="render_chapter_list" />
      </el-form-item>

      <div class="chapter-list" v-if="userConfig.simpleChapterView">
        <chapterSimple
          v-for="(i, k) in chapterList"
          :key="k"
          :chapterInfo="i"
          :sourceWebsite="sourceWebsite"
          @click="go_browse(i)"
          @contextmenu.prevent="context_menu(i, k)" />
      </div>
      <div class="chapter-list" v-else>
        <chapter
          v-for="(i, k) in chapterList"
          :key="k"
          :chapterInfo="i"
          :sourceWebsite="sourceWebsite"
          @click="go_browse(i)"
          @contextmenu.prevent="context_menu(i, k)" />
      </div>
    </div>

    <div class="bottom"></div>

    <el-dialog :title="$t('rightSidebar.editTags')" v-model="editTagsDialog">
      <mangaTagBox :mangaId="mangaInfo.mangaId" :tags="mangaInfo.tags" @update_tags="update_tags" @close_dialog="editTagsDialog = false" />
    </el-dialog>

    <manga-modify v-model:editMangaDialog="editMangaDialog" @reload="render_meta" :mangaInfo="mangaInfo" />

    <el-dialog :title="$t('rightSidebar.editCover')" v-model="editCover">
      <div class="cover-setting">
        <div :class="['cover-setting-box', {active: item.active}]" v-for="item in covers" :key="item.metaId">
          <img :src="item.blob" alt="cover" @click="choose_cover(item.metaFile)" />
        </div>
      </div>
    </el-dialog>

    <el-dialog :title="$t('rightSidebar.editMetas')" v-model="editMetasDialog">
      <el-form :model="metaForm" label-width="auto" style="max-width: 600px">
        <el-form-item label="漫画名称">
          <el-input v-model="metaForm.title" placeholder="请输入漫画名称"></el-input>
        </el-form-item>
        <el-form-item label="作者">
          <el-input v-model="metaForm.author" placeholder="请输入作者名"></el-input>
        </el-form-item>
        <el-form-item label="发布时间">
          <el-date-picker v-model="metaForm.publishDate" type="date" placeholder="请选择发布时间" />
        </el-form-item>
        <el-form-item label="评分">
          <el-input v-model="metaForm.star" placeholder="请输入评分"></el-input>
        </el-form-item>
        <el-form-item label="简介">
          <el-input type="textarea" v-model="metaForm.describe" placeholder="请输入漫画简介"></el-input>
        </el-form-item>
        <!-- 是否写入json -->
        <el-form-item label="存为JSON">
          <el-switch v-model="metaWriteJson"></el-switch>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="update_metas">保存</el-button>
          <el-button @click="editMetasDialog = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

    <el-dialog :title="$t('mangaInfo.mangaShareDialogTitle')" v-model="mangaShareDialog">
      <share :mangaInfo="mangaInfo" @close_dialog="mangaShareDialog = false" />
    </el-dialog>

    <right-sidebar
      :chapter-info="chapterInfo"
      v-model:rightSidebarVisible="rightSidebarVisible"
      @reload="render_chapter_list"
      @close="
        () => {
          rightSidebarVisible = false;
        }
      " />
  </div>
</template>

<script lang="ts" setup>
import {useRoute, useRouter} from 'vue-router';
import {onMounted, ref, reactive, computed} from 'vue';
import mangaApi from '@/api/manga';
import imageApi from '@/api/image';
import {config, userConfig} from '@/store';
import {tagItemType} from '@/type/tag';
import {metaType, metaInit} from '@/type/meta';
import {mangaType, mangaInit} from '@/type/manga';
import {chapterInit, chapterType} from '@/type/chapter';
import chapterApi from '@/api/chapter';
import lastesApi from '@/api/latest';
import collectApi from '@/api/collect';
import mangaTagBox from '@/views/manga-info/components/manga-tag-box.vue';
import share from '@/components/share.vue';
import useBrowseStore from '@/store/browse';
import chapter from './components/chapter.vue';
import chapterSimple from './components/chapter-simple.vue';
import rightSidebar from '../chapter-list/right-sidebar.vue';
import mangaModify from '@/views/manga-manage/components/mangaModify.vue';
const browse: any = useBrowseStore();
const router = useRouter();
const route = useRoute();

const metaForm = reactive({
  title: '',
  author: '',
  publishDate: '',
  star: '',
  describe: '',
});

const continueRead = ref({
  chapterId: 0,
  chapterName: '',
  chapterNumber: 0,
  page: 0,
});

const chapterList = ref<chapterType[]>([]);
const editMangaDialog = ref(false);

let mangaInfo = reactive<mangaType>(mangaInit);

let hasLatest = ref(false);

let banner = ref<metaType[]>([]);
let covers = ref<metaType[]>([]);
let character = ref<metaType[]>([]);
let mangaCover = ref<string>('');
let isCollect = ref(false);
let editTagsDialog = ref(false);
let editCover = ref(false);
let editMetasDialog = ref(false);
let mangaShareDialog = ref(false);
let bannerModel = ref<string>('toptoon');
let bannerBg = ref<metaType>();
let hasManyCover = ref(false);
let metaWriteJson = ref(true);

let chapterInfo = ref<chapterType>(chapterInit);
let chapterListDesc = ref(false);

let rightSidebarVisible = ref(false);

let sourceWebsite = ref('');

// 轮播自动滚动时间间隔 默认为6秒钟
const interval = ref(6 * 1000);

const carouselType = computed(() => {
  const screen = config.screenType;

  if (['middle', 'large', '2k', '4k'].includes(screen)) {
    return 'card';
  } else {
    return '';
  }
});

const infoColum = computed(() => {
  const screen = config.screenType;

  switch (screen) {
    case 'large':
      return 3;
    case 'middle':
      return 2;
    case 'small':
      return 1;
    case 'mini':
      return 1;
    default:
      return 4;
  }
});

onMounted(async () => {
  // 渲染元数据
  await render_meta();
  await get_first_chapter();
  await get_latest_reading();
  await render_chapter_list();

  get_collect_status();
});

/**
 * @description: 获取漫画首个章节
 * @return {*}
 */
async function get_first_chapter() {
  const mangaId = mangaInfo.mangaId;
  if (!mangaId) return;

  continueRead.value = await chapterApi.get_first(mangaId, 'number');
}

/**
 * @description: 获取最后一次的阅读记录
 * @return {*}
 */
async function get_latest_reading() {
  const mangaId = mangaInfo.mangaId;
  if (!mangaId) return;

  const latest = await lastesApi.get_latest(mangaId);
  if (!latest) return;

  if (latest.finish && latest.nextChapter) {
    continueRead.value = latest.nextChapter;
    continueRead.value.page = 1;
  } else if (latest.finish) {
    // 已读完全部漫画
    hasLatest.value = false;
    return;
  } else {
    continueRead.value = latest.chapter;
    continueRead.value.page = latest.page;
    continueRead.value.chapterId = latest.chapterId;
  }

  hasLatest.value = true;
}

/**
 * @description: 开始阅读漫画第一章
 * @return {*}
 */
async function go_chapter() {
  const chapterInfo = continueRead.value;
  if (!chapterInfo) return;
  // 使用pinia存储页码
  if (chapterInfo.page && chapterInfo.page > 1) {
    browse.page = chapterInfo.page;
    localStorage.setItem('pageJump', chapterInfo.page.toString());
  } else {
    browse.page = 1;
  }

  const browsePageRoute = {
    name: mangaInfo.browseType,
    query: {
      mediaId: mangaInfo.mediaId,
      mangaId: mangaInfo.mangaId,
      chapterId: chapterInfo?.chapterId,
    },
  };

  if (userConfig.openNewTab) {
    const newUrl = router.resolve(browsePageRoute);
    window.open(newUrl.href, '_blank');
  } else {
    router.push(browsePageRoute);
  }
}

/**
 * @description: 去往漫画章节列表页面
 * @return {*}
 */
function go_chapter_list() {
  browse.chapterListPage = 1;
  router.push({
    name: 'chapter-list',
    query: {
      mangaId: mangaInfo.mangaId,
    },
    params: {
      browseType: mangaInfo.browseType,
      clear: '1',
    },
  });
}

/**
 * @description: 渲染元数据信息
 * @return {*}
 */
async function render_meta() {
  const mangaId = Number(route.query.mangaId);
  Object.assign(mangaInfo, await mangaApi.get_manga_info(mangaId));
  if (mangaInfo?.media?.sourceWebsite) {
    sourceWebsite.value = mangaInfo?.media?.sourceWebsite;
  }

  // 漫画封面
  mangaCover.value = await imageApi.get({file: mangaInfo.mangaCover});

  if (!mangaInfo.metas) return;

  const title = mangaInfo.metas.find((item: metaType) => item.metaName === 'title')?.metaContent;
  if (title) mangaInfo.title = title;

  const author = mangaInfo.metas.find((item: metaType) => item.metaName === 'author')?.metaContent;
  if (author) mangaInfo.author = author;

  const publishDate = mangaInfo.metas.find((item: metaType) => item.metaName === 'publishDate')?.metaContent;
  if (publishDate) mangaInfo.publishDate = publishDate;

  const describe = mangaInfo.metas.find((item: metaType) => item.metaName === 'describe')?.metaContent;
  if (describe) mangaInfo.describe = describe;

  const star = mangaInfo.metas.find((item: metaType) => item.metaName === 'star')?.metaContent;
  if (star) mangaInfo.star = star;

  // 封面
  covers.value = mangaInfo.metas.filter((item: metaType) => item.metaName === 'cover');
  hasManyCover.value = covers.value.length > 0;

  // 广告图
  banner.value = mangaInfo.metas.filter((item: metaType) => /banner/.test(item.metaName));
  bannerBg.value = banner.value.find((item: metaType) => /bannerBackground/.test(item.metaFile));
  if (bannerBg.value) bannerModel.value = 'toomics';
  banner.value.forEach(async (item: metaType) => {
    item.blob = await imageApi.get({file: item.metaFile});
  });

  // 将图片进行排序
  banner.value.sort((a: any, b: any) => {
    return a.metaFile - b.metaFile;
  });

  // 角色信息
  character.value = mangaInfo.metas.filter((item: metaType) => item.metaName === 'character');
  character.value.forEach(async (item: metaType) => {
    const blob = await imageApi.get({file: item.metaFile});
    item.blob = blob;
  });
}

async function render_chapter_list() {
  chapterList.value = [];
  const mangaId = mangaInfo.mangaId;
  if (!mangaId) return;

  const chapterListResponse = await chapterApi.get({mangaId, mediaId: mangaInfo.mediaId, order: chapterListDesc.value ? 'numberDesc' : 'number'});
  chapterList.value = chapterListResponse.list;
}

function go_browse(chapter: any) {
  if (chapter?.latest?.finish) {
    browse.page = 1;
  } else if (chapter?.latest) {
    browse.page = chapter.latest.page;
    localStorage.setItem('pageJump', chapter.latest.page);
  } else {
    browse.page = 1;
  }

  const browsePageRoute = {
    name: chapter.browseType,
    query: {
      mediaId: chapter.mediaId,
      mangaId: chapter.mangaId,
      chapterId: chapter.chapterId,
    },
  };

  if (userConfig.openNewTab) {
    const newUrl = router.resolve(browsePageRoute);
    window.open(newUrl.href, '_blank');
  } else {
    router.push(browsePageRoute);
  }
}

/**
 * 打开右侧菜单
 */
function context_menu(info: any, key: number) {
  chapterInfo.value = info;
  rightSidebarVisible.value = true;
}

/**
 * @description: 角色列表的横向滚动事件
 * @param {*} event
 * @return {*}
 */
function character_wheel(event: any) {
  const content = document.querySelector('.character-scroll');
  if (!content) return;
  event.preventDefault();

  content.scrollLeft += event.deltaY;
}

async function get_collect_status() {
  if (!mangaInfo.mangaId) return;
  isCollect.value = await collectApi.is_collect('manga', mangaInfo.mangaId);
}

async function collect_manga() {
  if (!mangaInfo.mangaId) return;
  await collectApi.add_collect(
    Object.assign(mangaInfo, {
      collectType: 'manga',
    })
  );

  get_collect_status();
}

async function remove_collect() {
  if (!mangaInfo.mangaId) return;
  await collectApi.remove_collect('manga', mangaInfo.mangaId);
  get_collect_status();
}

function open_covers_edit() {
  editCover.value = true;
  covers.value.forEach(async (item: metaType) => {
    item.active = item.metaFile === mangaInfo.mangaCover;
    const blob = await imageApi.get({file: item.metaFile});
    item.blob = blob;
  });
}

function open_metas_edit() {
  editMetasDialog.value = true;
  Object.assign(metaForm, mangaInfo);
}

function choose_cover(metaFile: string) {
  if (!metaFile) return;
  covers.value.forEach((item: metaType) => {
    item.active = item.metaFile === metaFile;
  });
  mangaApi
    .update_manga({
      mangaId: mangaInfo.mangaId,
      mangaCover: metaFile,
    })
    .then(() => {
      mangaInfo.mangaCover = metaFile;
      editCover.value = false;
    })
    .catch((err: any) => {
      console.error('更新封面失败:', err);
    });
}

async function update_metas() {
  if (!mangaInfo.mangaId) return;
  await mangaApi.update_manga_meta(metaForm, metaWriteJson.value);
  editMetasDialog.value = false;
  await render_meta();
}

/**
 * @description: 更新详情页的tag列表
 * @param {*} tagsParams
 * @return {*}
 */
function update_tags(tagsParams: tagItemType[]) {
  mangaInfo.tags = tagsParams;
}
</script>

<style lang="less" scoped>
.manga-info {
  color: @s-back-text;
}

:deep(.el-form-item__label) {
  --el-text-color-regular: @s-back-text;
}

:deep(.el-carousel__container) {
  height: auto !important;
}

:deep(.el-carousel__mask) {
  background-color: transparent;
}

.chapter-list {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 1rem 2rem 0;
  // justify-content: space-between;
}

.banner-toomics {
  position: relative;
  width: 100%;
  height: 32rem;

  img {
    position: absolute;
    bottom: 0;
    display: block;
    margin: 0 auto;
    object-fit: cover;
  }

  &-fore {
    height: 100%;
    max-width: 100%;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1;
  }

  &-back {
    width: 100%;
    height: 100%;
    z-index: 0;
    filter: blur(2px);
  }
}

// 自动换行
.continue-read {
  white-space: normal;
  overflow: hidden;
}

.cover-setting {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;

  .cover-setting-box {
    width: 20rem;
    height: 30rem;
    border-radius: 1rem;
    overflow: hidden;
    position: relative;
    border: 0.8rem solid var(--el-border-color);

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    &:hover {
      cursor: pointer;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
    }

    &.active {
      border-color: var(--el-color-primary);
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
    }
  }
}

.character-scroll {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
  gap: 0.6rem;
  padding: 1rem;
}

.top {
  margin-top: 2rem;
}

.carousel {
  height: auto;
}

.banner {
  display: block;
  margin: 0 auto;
  max-width: 100%;
}

.seat {
  opacity: 0;
}

.title {
  font-size: 2.4rem;
  text-align: center;
  margin-bottom: 2rem;
}

.character-title {
  color: var(--el-text-color-primary);
  font-size: 1.6rem;
  font-weight: bold;
  margin-bottom: 1rem;
  text-indent: 2rem;
}

.character {
  white-space: nowrap;
  margin-top: 0;

  &-scroll {
    display: flex;
  }

  &-item {
    display: flex;
    padding: 1rem;
    margin: 0 1rem;
    border: 0.4rem @s-border solid;
    border-radius: 2rem;

    img {
      width: 12rem;
    }

    .right {
      margin-left: 1rem;
      width: 20rem;
      white-space: initial;
      text-indent: 1rem;
      line-height: 1.5;
    }

    .description {
      font-size: 1.2rem;
    }
  }
}

.meta-info {
  margin: 2rem 2rem 0 2rem;
  color: @s-back-text;
}

:deep(.el-descriptions__body) {
  border-radius: 2rem;
  background-color: transparent;
}

.btn-box {
  display: flex;
  margin: 0 2rem;
  flex-wrap: wrap;
  gap: 1rem;

  .el-button + .el-button {
    margin-left: 0;
  }

  .btn {
    width: 24%;
    margin-bottom: 1rem;
  }
}

// 底层占位符 怕手机点不到
.bottom {
  margin-bottom: 6rem;
}

.op-range {
  margin-left: 2rem;
}

// 封面
.cover-img {
  display: block;
  margin: 0 auto;
  min-width: 14rem;
  height: 40rem;
}

@media only screen and (min-width: 4096px) {
  .banner {
    width: 100rem;
  }
}

@media only screen and (max-width: 4095px) and (min-width: 2560px) {
  .banner {
    width: 80rem;
  }
}

@media only screen and (max-width: 2559px) and (min-width: 1920px) {
  .banner {
    width: 60rem;
  }
}

@media only screen and (max-width: 1919px) and (min-width: 1200px) {
  .banner {
    width: 50rem;
  }

  .banner-toomics {
    height: 20rem;
  }
}

@media only screen and (max-width: 1199px) and (min-width: 768px) {
  .top {
    margin-top: 0;
  }

  .chapter-list {
    gap: 0.6rem;
  }

  .character {
    img {
      width: 8rem;
    }

    &-item {
      padding: 0.6rem;
      border-radius: 1.2rem;
    }

    .right {
      width: 14rem;
      line-height: 1.5;
    }
  }

  .banner {
    width: 40rem;
  }

  .banner-toomics {
    height: 20rem;
  }
}

@media only screen and (max-width: 767px) {
  .top {
    margin-top: 0;
  }

  .chapter-list {
    gap: 0.4rem;
  }

  .character {
    margin-top: 2rem;

    img {
      width: 6rem;
    }

    &-item {
      padding: 0.4rem;
      border-radius: 1rem;
    }

    .right {
      width: 14rem;
      line-height: 1.5;
    }
  }

  .btn-box .btn {
    width: 48%;
  }

  .banner-toomics {
    height: 10rem;
  }
}
</style>
